package org.sevenless.vul;

import com.vaadin.Application;
import com.vaadin.ui.*;
import com.vaadin.data.*;
import com.vaadin.event.*;
import java.lang.reflect.Method;
import java.io.File;
import java.util.Stack;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
//import org.apache.log4j.Logger;

public abstract class VulComposer extends Window implements 
  ComponentContainer.ComponentAttachListener,
  ComponentContainer.ComponentDetachListener,
  Property.ValueChangeListener,
  Property.ReadOnlyStatusChangeListener,
  Container.ItemSetChangeListener,
  Container.PropertySetChangeListener,
  FieldEvents.BlurListener,
  FieldEvents.FocusListener,
  LayoutEvents.LayoutClickListener,
  Button.ClickListener,
  MouseEvents.ClickListener,
  ItemClickEvent.ItemClickListener,
  Table.ColumnResizeListener,
  Table.FooterClickListener,
  Table.HeaderClickListener,
  Tree.CollapseListener,
  Tree.ExpandListener,
  Upload.FailedListener,
  Upload.FinishedListener,
  Upload.StartedListener,
  Upload.SucceededListener,
  MenuBar.Command,
  Window.CloseListener,
  Window.ResizeListener
{
  //private static Logger log=Logger.getLogger(VulComposer.class);
  private Application app;
  private ComponentContainer rootContainer = null;
  private ComponentContainer curCont = null;
  private Stack<ComponentContainer> contStack = new Stack<ComponentContainer>();
  private VulTags tags = new VulTags();
  Map<Object,Method> attachMap = null;
  Map<Object,Method> detachMap = null;
  Map<Object,Method> valChangeMap = null;
  Map<Object,Method> roChangeMap = null;
  Map<Object,Method> itemChangeMap = null;
  Map<Object,Method> propChangeMap = null;
  Map<Object,Method> blurMap = null;
  Map<Object,Method> focusMap = null;
  Map<Object,Method> layoutMap = null;
  Map<Object,Method> btnClickMap = null;
  Map<Object,Method> mouseClickMap = null;
  Map<Object,Method> itemClickMap = null;
  Map<Object,Method> colResizeMap = null;
  Map<Object,Method> footerMap = null;
  Map<Object,Method> headerMap = null;
  Map<Object,Method> collapseMap = null;
  Map<Object,Method> expandMap = null;
  Map<Object,Method> upFailMap = null;
  Map<Object,Method> upFinishMap = null;
  Map<Object,Method> upStartMap = null;
  Map<Object,Method> upSucceedMap = null;
  Map<String,Method> menuMap = null;
  Method closeMethod = null;
  Method resizeMethod = null;
  
  public VulComposer(Application app) throws Exception {
    this.app = app;
    beforeCompose();
    compose();
    afterCompose();
  }
  
  public abstract String getVulName();
  
  public ComponentContainer getRootContainer() {
    return rootContainer;
  }
  
  public void beforeCompose() {
  }
  
  public void afterCompose() {
  }
  
  public void compose() throws Exception {
    String baseDir = app.getContext().getBaseDirectory().toString();
    //System.err.println("in compose base dir: "+baseDir);
    curCont = null;
    File f = new File(baseDir+"/"+getVulName());
    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
    Document doc = docBuilder.parse(f);
    Node n = doc.getDocumentElement();
    String nodeName = n.getNodeName().toLowerCase();
    if (!tags.isContainer(nodeName)) {
      throw new Exception("root node must be a container");
    }
    curCont = (ComponentContainer)setupComponent(n, nodeName);
    rootContainer = curCont;
    try {
      loadNode(n);
    } catch (Exception e) {
      System.err.println("error loading node: "+e.getMessage());
      e.printStackTrace(System.err);
    }
    if (rootContainer instanceof Window) wireWindowEvents();
  }

  public void loadNode(Node n) throws Exception {
    NodeList childNodes = n.getChildNodes();
    for (int i=0; i<childNodes.getLength(); i++) {
      Node cn = childNodes.item(i);
      if (cn.getNodeType() != Node.ELEMENT_NODE) continue;
      String nodeName = cn.getNodeName().toLowerCase();

      if (tags.isContainer(nodeName)) {
        //System.err.println("it's a container");
        contStack.push(curCont);
        curCont = (ComponentContainer)setupComponent(cn, nodeName);
        loadNode(cn);
        curCont = contStack.pop();
      }
      else if (tags.isComponent(nodeName)) {
        //System.err.println("it's a component");
        setupComponent(cn, nodeName);
      }
    }
  }
  
  private Component setupComponent(Node n, String name) throws Exception {
    //System.err.println("component: "+name);
    VulAttributes va = tags.getComponentAttr(name);
    if (va == null) va = tags.getContainerAttr(name);
    if (va == null) {
      //System.err.println("no attributes");
      return null;
    }
    Class c = va.getCompClass();
    Object o = c.newInstance();
    String id = handleAttributes(n, c, o, va);
    if (id.length() > 0) {
      wireObject(o, id);
      wireEvents(o, id);
      if (o instanceof MenuBar) {
        loadMenuItems(n, (MenuBar)o, id);
      } else if (o instanceof AbstractSelect) {
        loadSelectItems(n, (AbstractSelect)o);
      }
    }
    Component comp = (Component)o;
    if (curCont != null) addComponentToContainer(n,comp,curCont);
    return comp;
  }
  
  private void loadSelectItems(Node n, AbstractSelect a) {
    NodeList childNodes = n.getChildNodes();
    for (int i=0; i<childNodes.getLength(); i++) {
      Node cn = childNodes.item(i);
      if (cn.getNodeType() != Node.ELEMENT_NODE) continue;
      String nodeName = cn.getNodeName().toLowerCase();
      if (!nodeName.equals("item")) continue;
      String caption = ((Element)n).getAttribute("caption");
      if (caption.length() == 0) continue;
      a.addItem(caption);
    }
  }
  
  private void loadMenuItems(Node n, MenuBar mb, String id) {
    NodeList childNodes = n.getChildNodes();
    if (childNodes.getLength() == 0) return;
    Method m = null;
    String ms = "onCommand$"+id;
    try {
      m = this.getClass().getMethod(ms, new Class[] {Button.ClickEvent.class});
    } catch (java.lang.NoSuchMethodException e) {
    }
    if ((m != null) && (menuMap == null)) {
      menuMap = new HashMap<String, Method>();
    }
    for (int i=0; i<childNodes.getLength(); i++) {
      Node cn = childNodes.item(i);
      if (cn.getNodeType() != Node.ELEMENT_NODE) continue;
      String nodeName = cn.getNodeName().toLowerCase();
      if (!nodeName.equals("item")) continue;
      String caption = ((Element)n).getAttribute("caption");
      if (caption.length() == 0) continue;
      MenuBar.MenuItem mi = mb.addItem(caption, this);
      if (m != null) menuMap.put(Integer.toString(mi.getId()), m);
      recurseMenuItems(cn, mi, m);
    }
  }
  
  private void recurseMenuItems(Node n, MenuBar.MenuItem mi, Method m) {
    NodeList childNodes = n.getChildNodes();
    for (int i=0; i<childNodes.getLength(); i++) {
      Node cn = childNodes.item(i);
      if (cn.getNodeType() != Node.ELEMENT_NODE) continue;
      String nodeName = cn.getNodeName().toLowerCase();
      if (!nodeName.equals("item")) continue;
      String caption = ((Element)n).getAttribute("caption");
      if (caption.length() == 0) continue;
      MenuBar.MenuItem cmi = mi.addItem(caption, this);
      if (m != null) menuMap.put(Integer.toString(cmi.getId()), m);
      recurseMenuItems(cn, cmi, m);
    }
  }
  
  private void addComponentToContainer(Node n, Component c, ComponentContainer cont) throws Exception {
    Element e = (Element)n;
    String sattr;
    if (cont instanceof AbsoluteLayout) {
      sattr = e.getAttribute("position");
      if (sattr.length() > 0) {
        ((AbsoluteLayout)cont).addComponent(c, sattr);
      } else {
        cont.addComponent(c);
      }
    } else if (cont instanceof FormLayout) {
      cont.addComponent(c);
      sattr = e.getAttribute("alignment");
      if (sattr.length() > 0) {
        ((FormLayout)cont).setComponentAlignment(c, sattr);
      }
    } else if (cont instanceof GridLayout) {
      sattr = e.getAttribute("alignment");
      if (sattr.length() > 0) {
        cont.addComponent(c);
        ((GridLayout)cont).setComponentAlignment(c, sattr);
      } else {
        String row = e.getAttribute("row");
        String col = e.getAttribute("col");
        if ((row.length() > 0) && (col.length() > 0)) {
          try {
            ((GridLayout)cont).addComponent(c, Integer.parseInt(col), Integer.parseInt(row));
          } catch (NumberFormatException ne) {
            cont.addComponent(c);
          }
        } else {
          cont.addComponent(c);
        }
      }
    } else if ( (cont instanceof HorizontalLayout) || (cont instanceof VerticalLayout) ){
      cont.addComponent(c);
      sattr = e.getAttribute("alignment");
      if (sattr.length() > 0) {
        ((AbstractOrderedLayout)cont).setComponentAlignment(c, sattr);
      }
      sattr = e.getAttribute("expand");
      if (sattr.length() > 0) {
        try {
          ((AbstractOrderedLayout)cont).setExpandRatio(c, Float.parseFloat(sattr));
        } catch (NumberFormatException ne) {
        }
      }
    } else if ( (cont instanceof Window) || (c instanceof ComponentContainer) ){
      ((Window)cont).setContent((ComponentContainer)c);
    } else {
      cont.addComponent(c);
    }
  }
  
  private String handleAttributes(Node n, Class c, Object o, VulAttributes va) {
    NamedNodeMap nm = n.getAttributes();
    String id="";
    for (int i=0; i<nm.getLength(); i++) {
      Node an = nm.item(i);
      String attr = an.getNodeName().toLowerCase();
      String val = an.getNodeValue().toLowerCase();
      if (attr.equals("id")) {
        id = an.getNodeValue();
        continue;
      }
      Method m = va.getMethod(attr);
      if (m == null) {
        continue;
      }
      try {
        Class[] pcs = m.getParameterTypes();
        Class pc = null;
        Object param = null;
        if (pcs.length > 0) {
          pc = pcs[0];
          param = convertStringToType(c,pc,attr,val);
        }
        if (pcs.length == 0)
          m.invoke(o);
        else
          m.invoke(o, param);
      } catch (Exception e) {
        System.err.println("Exception invoking attr: "+e.getMessage());
      }  
    }
    return id;
  }
  
  private void wireObject(Object o, String id) throws Exception {
    try {
      java.lang.reflect.Field f = this.getClass().getDeclaredField(id);
      f.setAccessible(true);
      f.set(this,o);
    } catch (java.lang.NoSuchFieldException e) {
      System.err.println("could not wire "+id);
    } catch (Exception ex) {
      System.err.println("wire object error: "+ex.getClass().getName()+" - "+ex.getMessage());
    }
  }
  
  private void wireEvents(Object o, String id) throws Exception {
    String ms;
    if (o instanceof ComponentContainer) {
      ms = "onAttach$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {ComponentContainer.ComponentAttachEvent.class});
        if (attachMap == null) attachMap = new HashMap<Object,Method>();
        attachMap.put(o,m);
        ((ComponentContainer)o).addListener((ComponentContainer.ComponentAttachListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onDetach$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {ComponentContainer.ComponentDetachEvent.class});
        if (detachMap == null) detachMap = new HashMap<Object,Method>();
        detachMap.put(o,m);
        ((ComponentContainer)o).addListener((ComponentContainer.ComponentDetachListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Property.ValueChangeNotifier) {
      ms = "onChange$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Property.ValueChangeEvent.class});
        if (valChangeMap == null) valChangeMap = new HashMap<Object,Method>();
        valChangeMap.put(o,m);
        ((Property.ValueChangeNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Property.ReadOnlyStatusChangeNotifier) {
      ms = "onReadOnlyChange$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Property.ReadOnlyStatusChangeEvent.class});
        if (roChangeMap == null) roChangeMap = new HashMap<Object,Method>();
        roChangeMap.put(o,m);
        ((Property.ReadOnlyStatusChangeNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Container.ItemSetChangeNotifier) {
      ms = "onItemChange$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Container.ItemSetChangeEvent.class});
        if (itemChangeMap == null) itemChangeMap = new HashMap<Object,Method>();
        itemChangeMap.put(o,m);
        ((Container.ItemSetChangeNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Container.PropertySetChangeNotifier) {
      ms = "onPropChange$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Container.PropertySetChangeEvent.class});
        if (propChangeMap == null) propChangeMap = new HashMap<Object,Method>();
        propChangeMap.put(o,m);
        ((Container.PropertySetChangeNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof FieldEvents.BlurNotifier) {
      ms = "onBlur$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {FieldEvents.BlurEvent.class});
        if (blurMap == null) blurMap = new HashMap<Object,Method>();
        blurMap.put(o,m);
        ((FieldEvents.BlurNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof FieldEvents.FocusNotifier) {
      ms = "onFocus$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {FieldEvents.FocusEvent.class});
        if (focusMap == null) focusMap = new HashMap<Object,Method>();
        focusMap.put(o,m);
        ((FieldEvents.FocusNotifier)o).addListener(this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof AbstractOrderedLayout) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {LayoutEvents.LayoutClickEvent.class});
        if (layoutMap == null) layoutMap = new HashMap<Object,Method>();
        layoutMap.put(o,m);
        ((AbstractOrderedLayout)o).addListener((LayoutEvents.LayoutClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof AbsoluteLayout) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {LayoutEvents.LayoutClickEvent.class});
        if (layoutMap == null) layoutMap = new HashMap<Object,Method>();
        layoutMap.put(o,m);
        ((AbsoluteLayout)o).addListener((LayoutEvents.LayoutClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof CssLayout) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {LayoutEvents.LayoutClickEvent.class});
        if (layoutMap == null) layoutMap = new HashMap<Object,Method>();
        layoutMap.put(o,m);
        ((CssLayout)o).addListener((LayoutEvents.LayoutClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof FormLayout) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {LayoutEvents.LayoutClickEvent.class});
        if (layoutMap == null) layoutMap = new HashMap<Object,Method>();
        layoutMap.put(o,m);
        ((FormLayout)o).addListener((LayoutEvents.LayoutClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof GridLayout) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {LayoutEvents.LayoutClickEvent.class});
        if (layoutMap == null) layoutMap = new HashMap<Object,Method>();
        layoutMap.put(o,m);
        ((GridLayout)o).addListener((LayoutEvents.LayoutClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Button) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Button.ClickEvent.class});
        if (btnClickMap == null) btnClickMap = new HashMap<Object,Method>();
        btnClickMap.put(o,m);
        ((Button)o).addListener((Button.ClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Embedded) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {MouseEvents.ClickEvent.class});
        if (mouseClickMap == null) mouseClickMap = new HashMap<Object,Method>();
        mouseClickMap.put(o,m);
        ((Embedded)o).addListener((MouseEvents.ClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Panel) {
      ms = "onClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {MouseEvents.ClickEvent.class});
        if (mouseClickMap == null) mouseClickMap = new HashMap<Object,Method>();
        mouseClickMap.put(o,m);
        ((Panel)o).addListener((MouseEvents.ClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Table) {
      ms = "onItemClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {ItemClickEvent.class});
        if (itemClickMap == null) itemClickMap = new HashMap<Object,Method>();
        itemClickMap.put(o,m);
        ((Table)o).addListener((ItemClickEvent.ItemClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onColResize$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Table.ColumnResizeEvent.class});
        if (colResizeMap == null) colResizeMap = new HashMap<Object,Method>();
        colResizeMap.put(o,m);
        ((Table)o).addListener((Table.ColumnResizeListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onFooterClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Table.FooterClickEvent.class});
        if (footerMap == null) footerMap = new HashMap<Object,Method>();
        footerMap.put(o,m);
        ((Table)o).addListener((Table.FooterClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onHeaderClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Table.HeaderClickEvent.class});
        if (headerMap == null) headerMap = new HashMap<Object,Method>();
        headerMap.put(o,m);
        ((Table)o).addListener((Table.HeaderClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Tree) {
      ms = "onItemClick$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {ItemClickEvent.class});
        if (itemClickMap == null) itemClickMap = new HashMap<Object,Method>();
        itemClickMap.put(o,m);
        ((Tree)o).addListener((ItemClickEvent.ItemClickListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onCollapse$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Tree.CollapseEvent.class});
        if (collapseMap == null) collapseMap = new HashMap<Object,Method>();
        collapseMap.put(o,m);
        ((Tree)o).addListener((Tree.CollapseListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onExpand$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Tree.ExpandEvent.class});
        if (expandMap == null) expandMap = new HashMap<Object,Method>();
        expandMap.put(o,m);
        ((Tree)o).addListener((Tree.ExpandListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
    if (o instanceof Upload) {
      ms = "onFail$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Upload.FailedEvent.class});
        if (upFailMap == null) upFailMap = new HashMap<Object,Method>();
        upFailMap.put(o,m);
        ((Upload)o).addListener((Upload.FailedListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onFinish$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Upload.FinishedEvent.class});
        if (upFinishMap == null) upFinishMap = new HashMap<Object,Method>();
        upFinishMap.put(o,m);
        ((Upload)o).addListener((Upload.FinishedListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onStart$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Upload.StartedEvent.class});
        if (upStartMap == null) upStartMap = new HashMap<Object,Method>();
        upStartMap.put(o,m);
        ((Upload)o).addListener((Upload.StartedListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
      ms = "onSucceed$"+id;
      try {
        Method m = this.getClass().getMethod(ms, new Class[] {Upload.SucceededEvent.class});
        if (upSucceedMap == null) upSucceedMap = new HashMap<Object,Method>();
        upSucceedMap.put(o,m);
        ((Upload)o).addListener((Upload.SucceededListener)this);
      } catch (java.lang.NoSuchMethodException e) {
      }
    }
  }
  
  private void wireWindowEvents() {
    try {
      Method m = this.getClass().getMethod("onClose", new Class[] {Window.CloseEvent.class});
      closeMethod = m;
    } catch (java.lang.NoSuchMethodException e) {
    }
    try {
      Method m = this.getClass().getMethod("onResize", new Class[] {Window.ResizeEvent.class});
      resizeMethod = m;
    } catch (java.lang.NoSuchMethodException e) {
    }
  }

  
  public void componentAttachedToContainer(ComponentContainer.ComponentAttachEvent event) {
    if (attachMap == null) return;
    Object o = event.getSource();
    try {
      Method m = attachMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void componentDetachedFromContainer(ComponentContainer.ComponentDetachEvent event) {
    if (detachMap == null) return;
    Object o = event.getSource();
    try {
      Method m = detachMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void valueChange(Property.ValueChangeEvent event) {
    if (valChangeMap == null) return;
    Object o = null;
    if (event instanceof Label.ValueChangeEvent) {
      o = ((Label.ValueChangeEvent)event).getSource();
    } else if (event instanceof Field.ValueChangeEvent) {
      o = ((Field.ValueChangeEvent)event).getSource();
    }
    if (o == null) return;
    try {
      Method m = valChangeMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }

  public void readOnlyStatusChange(Property.ReadOnlyStatusChangeEvent event) {
    if (roChangeMap == null) return;
    Object o = null;
    if (event instanceof AbstractField.ReadOnlyStatusChangeEvent) {
      o = ((AbstractField.ReadOnlyStatusChangeEvent)event).getSource();
    }
    if (o == null) return;
    try {
      Method m = roChangeMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void containerItemSetChange(Container.ItemSetChangeEvent event) {
    if (itemChangeMap == null) return;
    Object o = event.getContainer();
    try {
      Method m = itemChangeMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void containerPropertySetChange(Container.PropertySetChangeEvent event) {
    if (propChangeMap == null) return;
    Object o = event.getContainer();
    try {
      Method m = propChangeMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void blur(FieldEvents.BlurEvent event) {
    if (blurMap == null) return;
    Object o = event.getSource();
    try {
      Method m = blurMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void focus(FieldEvents.FocusEvent event) {
    if (focusMap == null) return;
    Object o = event.getSource();
    try {
      Method m = focusMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void layoutClick(LayoutEvents.LayoutClickEvent event) {
    if (layoutMap == null) return;
    Object o = event.getSource();
    try {
      Method m = layoutMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void buttonClick(Button.ClickEvent event) {
    if (btnClickMap == null) return;
    Object o = event.getSource();
    try {
      Method m = btnClickMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void click(MouseEvents.ClickEvent event) {
    if (mouseClickMap == null) return;
    Object o = event.getSource();
    try {
      Method m = mouseClickMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void itemClick(ItemClickEvent event) {
    if (itemClickMap == null) return;
    Object o = event.getSource();
    try {
      Method m = itemClickMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void columnResize(Table.ColumnResizeEvent event) {
    if (colResizeMap == null) return;
    Object o = event.getSource();
    try {
      Method m = colResizeMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void footerClick(Table.FooterClickEvent event) {
    if (footerMap == null) return;
    Object o = event.getSource();
    try {
      Method m = footerMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void headerClick(Table.HeaderClickEvent event) {
    if (headerMap == null) return;
    Object o = event.getSource();
    try {
      Method m = headerMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void nodeCollapse(Tree.CollapseEvent event) {
    if (collapseMap == null) return;
    Object o = event.getSource();
    try {
      Method m = collapseMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void nodeExpand(Tree.ExpandEvent event) {
    if (expandMap == null) return;
    Object o = event.getSource();
    try {
      Method m = expandMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void uploadFailed(Upload.FailedEvent event) {
    if (upFailMap == null) return;
    Object o = event.getSource();
    try {
      Method m = upFailMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void uploadFinished(Upload.FinishedEvent event) {
    if (upFinishMap == null) return;
    Object o = event.getSource();
    try {
      Method m = upFinishMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void uploadStarted(Upload.StartedEvent event) {
    if (upStartMap == null) return;
    Object o = event.getSource();
    try {
      Method m = upStartMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }
  
  public void uploadSucceeded(Upload.SucceededEvent event) {
    if (upSucceedMap == null) return;
    Object o = event.getSource();
    try {
      Method m = upSucceedMap.get(o);
      if (m != null) {
        m.invoke(this,event);
      }
    } catch (Exception e) {
    }
  }

  public void menuSelected(MenuBar.MenuItem selectedItem) {
    if (menuMap == null) return;
    try {
      Method m = menuMap.get(Integer.toString(selectedItem.getId()));
      if (m != null) {
        m.invoke(this,selectedItem);
      }
    } catch (Exception e) {
    }
  }
  
  public void windowClose(Window.CloseEvent event) {
    if (closeMethod == null) return;
    try {
      closeMethod.invoke(this,event);
    } catch (Exception e) {
    }
  }
  
  public void windowResized(Window.ResizeEvent event) {
    if (resizeMethod == null) return;
    try {
      resizeMethod.invoke(this,event);
    } catch (Exception e) {
    }
  }
  
  private Object convertStringToType(Class compClass, Class paramClass, String attr, String val) {
    if (paramClass == java.lang.String.class) {
      return val;
    } else if (paramClass == int.class) {
      if (attr.equals("orientation")) {
        if (val.equals("horizontal")) {
          return SplitPanel.ORIENTATION_HORIZONTAL;
        } else if (val.equals("vertical")) {
          return SplitPanel.ORIENTATION_VERTICAL;
        } else {
          return SplitPanel.ORIENTATION_HORIZONTAL;
        }
      } else if (attr.equals("headermode")) {
        if (val.equals("hidden")) {
          return Table.ROW_HEADER_MODE_HIDDEN;
        } else if (val.equals("id")) {
          return Table.ROW_HEADER_MODE_ID;
        } else if (val.equals("item")) {
          return Table.ROW_HEADER_MODE_ITEM;
        } else if (val.equals("property")) {
          return Table.ROW_HEADER_MODE_PROPERTY;
        } else if (val.equals("explicit")) {
          return Table.ROW_HEADER_MODE_EXPLICIT;
        } else if (val.equals("index")) {
          return Table.ROW_HEADER_MODE_INDEX;
        } else {
          return Table.ROW_HEADER_MODE_HIDDEN;
        }
      } else if (attr.equals("resolution")) {
        if (val.equals("year")) {
          return DateField.RESOLUTION_YEAR;
        } else if (val.equals("month")) {
          return DateField.RESOLUTION_MONTH;
        } else if (val.equals("day")) {
          return DateField.RESOLUTION_DAY;
        } else if (val.equals("hour")) {
          return DateField.RESOLUTION_HOUR;
        } else if (val.equals("min")) {
          return DateField.RESOLUTION_MIN;
        } else if (val.equals("sec")) {
          return DateField.RESOLUTION_SEC;
        } else if (val.equals("msec")) {
          return DateField.RESOLUTION_MSEC;
        } else {
          return DateField.RESOLUTION_DAY;
        }
      } else if (attr.equals("border")) {
        if (val.equals("default")) {
          return Window.BORDER_DEFAULT;
        } else if (val.equals("minimal")) {
          return Window.BORDER_MINIMAL;
        } else if (val.equals("none")) {
          return Window.BORDER_NONE;
        }
      } else {
        return Integer.parseInt(val);
      }
    } else if (paramClass == boolean.class) {
      if (val.equals("true")) {
        return new Boolean(true);
      } else {
        return new Boolean(false);
      }
    } else if (paramClass == com.vaadin.terminal.Resource.class) {
      String fName = val;
      if (val.startsWith("http://")) {
        return new com.vaadin.terminal.ExternalResource(fName);
      } else if (val.startsWith("file://")) {
        fName = val.substring(7);
        return new com.vaadin.terminal.FileResource(new File(fName),app);
      } else if (val.startsWith("theme://")) {
        fName = val.substring(8);
        return new com.vaadin.terminal.ThemeResource(fName);
      } else {
        return new com.vaadin.terminal.ThemeResource(fName);
      }
    } else if (paramClass == Layout.MarginInfo.class) {
      boolean top = false;
      boolean right = false;
      boolean bottom = false;
      boolean left = false;
      String[] vals = val.split(",");
      for (String v : vals) {
        String vv = v.trim();
        if (vv.equals("top")) top = true;
        else if (vv.equals("right")) right = true;
        else if (vv.equals("bottom")) bottom = true;
        else if (vv.equals("left")) left = true;
      }
      return new Layout.MarginInfo(top,right,bottom,left);
    }
    return null;
  }
  
}
